# =============================================================================
# 通用 Makefile 模板
# 支持 C/C++ 混合编译，自动查找源文件，支持 debug/release 模式，并行编译
# =============================================================================

# =============================================================================
# 并行编译设置
# =============================================================================
# 自动检测 CPU 核心数
NUM_CORES := $(shell nproc 2>/dev/null || sysctl -n hw.ncpu 2>/dev/null || echo 4)

# 并行编译选项
PARALLEL_FLAGS = -j$(NUM_CORES)

# 默认使用并行编译
MAKEFLAGS += $(PARALLEL_FLAGS)

# =============================================================================
# 编译器设置
# =============================================================================
CC = gcc
CXX = g++

# =============================================================================
# 项目名称设置
# =============================================================================
TARGET = app

# =============================================================================
# VCPKG 路径配置（使用变量便于维护和覆盖）
# =============================================================================
# 默认的 vcpkg 安装路径
VCPKG_X64 = /home/dldxdg/vcpkg/installed/x64-linux
VCPKG_X86 = /home/dldxdg/vcpkg/installed/x86-linux

# =============================================================================
# 头文件和库文件路径配置
# =============================================================================
# 头文件搜索路径 (-I 参数)
INCLUDE_PATHS = -I$(VCPKG_X64)/include \
                -I$(VCPKG_X86)/include \
				-I/usr/include/mysql

# 库文件搜索路径 (-L 参数)
LIBRARY_PATHS = -L$(VCPKG_X64)/lib \
                -L$(VCPKG_X86)/lib \
				-L/usr/local/lib

# 需要链接的库 (-l 参数)，这里添加 fmt 库
LIBS = -lfmt -lcrypt -lsoci_mysql -lsoci_core -lmysqlclient -lssl -lcrypto -lz -lzstd -lavformat -lavcodec -lavutil -lswscale -lswresample


# =============================================================================
# 源文件自动查找
# =============================================================================
# 自动查找当前目录下所有的 .c 和 .cpp 文件
C_SRCS = $(wildcard *.c)
CPP_SRCS = $(wildcard *.cpp)
SRCS = $(C_SRCS) $(CPP_SRCS)

# =============================================================================
# 对象文件生成规则
# =============================================================================
# 将 .c 文件转换为 .o 文件
C_OBJS = $(C_SRCS:.c=.o)
# 将 .cpp 文件转换为 .o 文件
CPP_OBJS = $(CPP_SRCS:.cpp=.o)
# 所有对象文件列表
OBJS = $(C_OBJS) $(CPP_OBJS)

# =============================================================================
# 编译选项配置
# =============================================================================
# 通用编译警告选项
CFLAGS_COMMON = -Wall -Wextra $(INCLUDE_PATHS)
CXXFLAGS_COMMON = -Wall -Wextra $(INCLUDE_PATHS)

# =============================================================================
# Debug 模式配置
# =============================================================================
# -g: 生成调试信息
# -O0: 不进行优化
# -DDEBUG: 定义 DEBUG 宏
CFLAGS_DEBUG = $(CFLAGS_COMMON) -g -O0 -DDEBUG
CXXFLAGS_DEBUG = $(CXXFLAGS_COMMON) -g -O0 -DDEBUG
# 链接选项：库路径
LDFLAGS_DEBUG = $(LIBRARY_PATHS)

# =============================================================================
# Release 模式配置
# =============================================================================
# -O2: 优化级别 2
# -DNDEBUG: 定义 NDEBUG 宏（禁用 assert）
CFLAGS_RELEASE = $(CFLAGS_COMMON) -O2 -DNDEBUG
CXXFLAGS_RELEASE = $(CXXFLAGS_COMMON) -O2 -DNDEBUG
# 链接选项：库路径 + 静态链接
LDFLAGS_RELEASE = -static $(LIBRARY_PATHS)

# =============================================================================
# 构建模式选择
# =============================================================================
# 默认构建模式为 debug
MODE ?= debug

# 根据选择的模式设置对应的编译选项
ifeq ($(MODE), release)
    # Release 模式选项
    CFLAGS = $(CFLAGS_RELEASE)
    CXXFLAGS = $(CXXFLAGS_RELEASE)
    LDFLAGS = $(LDFLAGS_RELEASE)
    TARGET_NAME = $(TARGET)
else
    # Debug 模式选项（默认）
    CFLAGS = $(CFLAGS_DEBUG)
    CXXFLAGS = $(CXXFLAGS_DEBUG)
    LDFLAGS = $(LDFLAGS_DEBUG)
    TARGET_NAME = $(TARGET)
endif

# =============================================================================
# 伪目标声明
# =============================================================================
.PHONY: all debug release clean help info all-parallel

# =============================================================================
# 默认目标：构建程序（使用并行编译）
# =============================================================================
all: $(TARGET_NAME)

# =============================================================================
# 并行编译目标
# =============================================================================
all-parallel: $(TARGET_NAME)

# =============================================================================
# Debug 构建目标（并行）
# =============================================================================
debug:
	@$(MAKE) MODE=debug $(PARALLEL_FLAGS)

# =============================================================================
# Release 构建目标（并行）
# =============================================================================
release:
	@$(MAKE) MODE=release $(PARALLEL_FLAGS)

# =============================================================================
# 主目标：链接所有对象文件生成可执行文件
# =============================================================================
$(TARGET_NAME): $(OBJS)
	@echo "链接 $(MODE) 模式: $@"
	@echo "使用库: $(LIBS)"
	$(CXX) $(OBJS) $(LDFLAGS) $(LIBS) -o $@
	@echo "构建完成: $@ (使用 $(NUM_CORES) 个核心)"

# =============================================================================
# C 源文件编译规则
# =============================================================================
%.o: %.c
	@echo "编译C $(MODE) 模式: $<"
	$(CC) $(CFLAGS) -c $< -o $@

# =============================================================================
# C++ 源文件编译规则
# =============================================================================
%.o: %.cpp
	@echo "编译C++ $(MODE) 模式: $<"
	$(CXX) $(CXXFLAGS) -c $< -o $@

# =============================================================================
# 清理构建文件
# =============================================================================
clean:
	@echo "清理构建文件..."
	rm -f $(OBJS) $(TARGET) $(TARGET)
	@echo "清理完成"

# =============================================================================
# 显示帮助信息
# =============================================================================
help:
	@echo "可用的 make 目标:"
	@echo "  make           - 编译 debug 模式（默认，使用 $(NUM_CORES) 核心）"
	@echo "  make debug     - 编译 debug 模式（使用 $(NUM_CORES) 核心）"
	@echo "  make release   - 编译 release 模式（静态链接，使用 $(NUM_CORES) 核心）"
	@echo "  make clean     - 清理所有构建文件"
	@echo "  make help      - 显示此帮助信息"
	@echo "  make info      - 显示当前构建配置"
	@echo ""
	@echo "并行编译选项:"
	@echo "  自动检测到 $(NUM_CORES) 个 CPU 核心"
	@echo "  手动指定核心数: make -jN (N=核心数量)"
	@echo ""
	@echo "环境变量覆盖示例:"
	@echo "  make VCPKG_X64=/custom/path/to/vcpkg/x64"
	@echo "  make VCPKG_X86=/custom/path/to/vcpkg/x86"

# =============================================================================
# 显示当前构建配置信息
# =============================================================================
info:
	@echo "================================================"
	@echo "当前构建配置信息"
	@echo "================================================"
	@echo "构建模式: $(MODE)"
	@echo "目标文件: $(TARGET_NAME)"
	@echo "CPU 核心数: $(NUM_CORES)"
	@echo "并行编译: 启用 ($(PARALLEL_FLAGS))"
	@echo "VCPKG x64 路径: $(VCPKG_X64)"
	@echo "VCPKG x86 路径: $(VCPKG_X86)"
	@echo "源文件: $(SRCS)"
	@echo "对象文件: $(OBJS)"
	@echo "头文件路径: $(INCLUDE_PATHS)"
	@echo "库文件路径: $(LIBRARY_PATHS)"
	@echo "链接库: $(LIBS)"
	@echo "CFLAGS: $(CFLAGS)"
	@echo "CXXFLAGS: $(CXXFLAGS)"
	@echo "LDFLAGS: $(LDFLAGS)"
	@echo "================================================"